iT邦幫忙

2022 iThome 鐵人賽

DAY 11
1

Rails 所做的工作比我們想像的更複雜,以 Controller 的 nest namespace 來說, Rails 必須知道要去哪裡載入這個檔案

Rails 載入相關的 source 檔案時,必須要先解析 Ruby 的語法
也因此我們才可以用多種方式來定義 class

舉個例來說,假設我們寫了一個 MyController,但 Rails 不知道他是哪個模組下的 MyController,他會去猜,但不是百分百猜中

Did It Work?

當你載入一個檔案並且呼叫 whatever_class.rb 時,無法確定這檔案裡面是不是有 whateverClass 的物件,甚至也無法確定 whateverClass 是不是一個 class。

使用 const_get 來自動載入,如果呼叫的方法裡面沒有相關的 class 就因為找不到而進入無限循環會壞掉

所以 const_get 不是一個好解法

所以我們來用 const_missing 處理這個狀況
而 const_missing 會再呼叫一次 const_get

step1 打開 Rainbow/lib/rainbow/dependencies.rb 改下列程式碼

# Rainbow/lib/rainbow/dependencies.rb
class Object
  def self.const_missing(c)
    return nil if @calling_const_missing
    @calling_const_missing = true
    require Rulers.to_underscore(c.to_s)
    klass = Object.const_get(c)
    @calling_const_missing = false
    klass 
  end
end

如果目前有其他的 const_missing 正在執行中,那麼再次執行會回傳 nil

更改後記得要刪除 rainbow-0.0.2.gem

step 2 git add .

step 3 重新安裝套件

> gem build rainbow.gemspec

  Successfully built RubyGem
  Name: rainbow
  Version: 0.0.2
  File: rainbow-0.0.2.gem

> gem install rainbow-0.0.2.gem

  Successfully installed rainbow-0.0.2
  Parsing documentation for rainbow-0.0.2
  Installing ri documentation for rainbow-0.0.2
  Done installing documentation for rainbow after 0 seconds
  1 gem installed

Re-re-reloading

當我們改變 classes 時, Rails 會預先重新載入,我們需要重啟伺服器

當 controller 被呼叫時, Rails 使用一種方法去清除及打包所有的 classes
這就是為什麼 Rails 運作的比較慢的原因

我們可以用 rerun 這個套件達成 reloading 的效果

打開 Gemfile 並且在 development 加入 rerun 這個套件

group :development do
  gem 'rerun', '~> 0.13.0'
  gem 'listen', '~> 3.1', '>= 3.1.5'
end

rerun 是一個指令套件,偵測到你的檔案有改變時,會重啟你的 server 及程序

接下來執行

> bundle install

執行後重新跑 server

bundle exec rerun -- rackup -p 3001

這時 rerun 就會開始偵測檔案的變動囉!


上一篇
Day 10 - Automatic Loading
下一篇
Day 12 View
系列文
從0開始刻 淺談 Rails 的運作魔法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言